package com.voice.server.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.voice.server.entity.AppToken;
import com.voice.server.enums.ResultEnum;
import com.voice.server.exception.SystemException;
import com.voice.server.repository.AppTokenRepository;
import com.voice.server.utils.SignUtil;
import com.wangjiacai.utils.utils.ResultVOUtil;
import com.wangjiacai.utils.web.service.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/*
 * @auther: wangjiacai
 *
 * @create: 2018-04-28 15:46:47
 */
@WebFilter(value = "/api/*")
public class ApiFilter implements Filter {

    @Autowired
    private RedisService redisService;
    @Autowired
    private ObjectMapper objectMapper;
    @Autowired
    private AppTokenRepository appTokenRepository;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        if(!validSign(request,response)) return;
        if(shouldFilter(request)){
            String token = request.getHeader("token");
            if(token==null){
                response.setContentType("application/json;charset=UTF-8");
                response.getWriter().write(objectMapper.writeValueAsString(ResultVOUtil.error(ResultEnum.ILLEGAL_USERS)));
                return;
            }
            if(!redisService.exists(token)){
                response.setContentType("application/json;charset=UTF-8");
                response.getWriter().write(objectMapper.writeValueAsString(ResultVOUtil.error(ResultEnum.TokenExpire)));
                return;
            }
        }
        filterChain.doFilter(request,response);
    }

    @Override
    public void destroy() {

    }
    public boolean shouldFilter(HttpServletRequest request) {
        if(request.getRequestURI().equals("/api/token")) return false;
        return true;
    }

    public boolean validSign(HttpServletRequest request,HttpServletResponse response) throws IOException {
        String appKey=request.getHeader("x-ca-key");
        if(StringUtils.isEmpty(appKey)) {
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write(objectMapper.writeValueAsString(ResultVOUtil.error(ResultEnum.XCaKeyNotExist)));
            return false;
        }
        String signature=request.getHeader("x-ca-signature");
        if(StringUtils.isEmpty(signature)) {
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write(objectMapper.writeValueAsString(ResultVOUtil.error(ResultEnum.XCaSignatureNotExist)));
            return false;
        }
        AppToken appToken=appTokenRepository.findByAppKey(appKey);
        try {
            String sign=SignUtil.sign(request,appToken.getAppSecret());
            if(!sign.equals(signature)){
                response.addHeader("x-ca-error-message",sign);
                response.setContentType("application/json;charset=UTF-8");
                response.getWriter().write(objectMapper.writeValueAsString(ResultVOUtil.error(ResultEnum.SignError)));
                return false;
            }
        }catch (SystemException e){
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write(objectMapper.writeValueAsString(ResultVOUtil.error(e.getCode(),e.getMessage())));
            return false;
        }
        return true;
    }

}
